package com.desay.pangoo.itmt.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.desay.pangoo.common.lite.lang.web.BusinessException;
import com.desay.pangoo.common.lite.lang.web.PangooWebConstant;
import com.desay.pangoo.common.lite.spring.web.ControllerCommonUtils;
import com.desay.pangoo.itmt.controller.vo.OrgChartVo;
import com.desay.pangoo.itmt.entity.OrgChartEntity;
import com.desay.pangoo.itmt.entity.WorkGroupEntity;
import com.desay.pangoo.itmt.enums.ExceptionCodeEnum;
import com.desay.pangoo.itmt.repository.OrgChartRepository;
import com.desay.pangoo.itmt.repository.WorkGroupRepository;
import com.desay.pangoo.itmt.repository.spec.ExpandCriteria;
import com.desay.pangoo.itmt.repository.spec.Restrictions;
import com.desay.pangoo.itmt.service.OrgChartService;
import com.desay.pangoo.itmt.utils.Base64Utils;
import com.desay.pangoo.itmt.constants.Constant;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @author uidq1163
 */
@Service
public class OrgChartServiceImpl implements OrgChartService {

	@Autowired
	private OrgChartRepository orgChartRepository;
	@Autowired
	private WorkGroupRepository workGroupRepository;
	@Value("${itmt.file-root-path}")
	private String fileRootPath;

	/**
	 * 用户头像base64:前缀
	 */
	private static final String BASE64_PRX = "data:image/jpeg;base64,";
	private static final String FIELD_WORKGROUP = "workGroup.id";
	private static final String FIELD_LOGIN = "login";
	private static final String FIELD_ORGROLE = "orgRole";

	@Override
	public Long create(OrgChartVo vo) {
		ExpandCriteria<OrgChartEntity> c = new ExpandCriteria<>();
		c.add(Restrictions.eq("parent.id", vo.getParentId(), true));
		c.add(Restrictions.eq(FIELD_LOGIN, vo.getLogin(), true));
		c.add(Restrictions.eq(FIELD_ORGROLE, vo.getOrgRole(), true));
		c.add(Restrictions.eq(FIELD_WORKGROUP, vo.getWorkGroupId(), true));
		List<OrgChartEntity> list = orgChartRepository.findAll(c);
		if (CollUtil.isNotEmpty(list)) {
			throw new BusinessException(ExceptionCodeEnum.ORG_CHART_HAS_EXIST);
		}
		OrgChartEntity orgChartEntity = new OrgChartEntity();
		BeanUtils.copyProperties(vo, orgChartEntity);
		if (null != vo.getParentId()) {
			Optional<OrgChartEntity> parentOption = orgChartRepository.findById(vo.getParentId());
			if (parentOption.isPresent()) {
				orgChartEntity.setParent(parentOption.get());
			}
		}
		if (null != vo.getWorkGroupId()) {
			// 检查工作组是否存在
			Optional<WorkGroupEntity> option = workGroupRepository.findById(vo.getWorkGroupId());
			if (option.isPresent()) {
				orgChartEntity.setWorkGroup(option.get());
			} else {
				throw new BusinessException(ExceptionCodeEnum.WORK_GROUP_NOT_EXIST);
			}
		}
		String user = ControllerCommonUtils.getHeader(PangooWebConstant.HEADER_NAME_USER_FULL_NAME);
		orgChartEntity.setCreator(user);
		if (!ObjectUtils.isEmpty(vo.getAvatar())) {
			orgChartEntity.setAvatar(transBaseToFile(orgChartEntity.getLogin(), vo.getAvatar()));
		}
		// 一个域下面只能存在一个leader
		if (vo.getOrgRole().equals(Constant.ROLE_TMT_LEADER)) {
			c = new ExpandCriteria<>();
			c.add(Restrictions.eq(FIELD_ORGROLE, vo.getOrgRole(), true));
			c.add(Restrictions.eq(FIELD_WORKGROUP, vo.getWorkGroupId(), true));
			list = orgChartRepository.findAll(c);
			if (CollUtil.isNotEmpty(list)) {
				throw new BusinessException(ExceptionCodeEnum.ORG_CHART_HAS_EXIST);
			}
		}
		orgChartRepository.save(orgChartEntity);
		return orgChartEntity.getId();

	}

	@Override
	public void delete(Long id) {
		Optional<OrgChartEntity> opiton = orgChartRepository.findById(id);
		if (!opiton.isPresent()) {
			throw new BusinessException(ExceptionCodeEnum.ORG_CHART_NOT_EXIST);
		}
		orgChartRepository.deleteById(id);
	}

	@Override
	public void update(Long id, OrgChartVo vo) {
		ExpandCriteria<OrgChartEntity> c = new ExpandCriteria<>();
		c.add(Restrictions.eq("parent.id", vo.getParentId(), true));
		c.add(Restrictions.eq(FIELD_LOGIN, vo.getLogin(), true));
		c.add(Restrictions.eq(FIELD_ORGROLE, vo.getOrgRole(), true));
		c.add(Restrictions.eq(FIELD_WORKGROUP, vo.getWorkGroupId(), true));
		c.add(Restrictions.ne("id", id, true));
		List<OrgChartEntity> list = orgChartRepository.findAll(c);
		if (CollUtil.isNotEmpty(list)) {
			throw new BusinessException(ExceptionCodeEnum.ORG_CHART_HAS_EXIST);
		}

		Optional<OrgChartEntity> opiton = orgChartRepository.findById(id);
		if (!opiton.isPresent()) {
			throw new BusinessException(ExceptionCodeEnum.ORG_CHART_NOT_EXIST);
		}
		OrgChartEntity existEntity = opiton.get();
		if (null != vo.getParentId()) {
			Optional<OrgChartEntity> parentOption = orgChartRepository.findById(vo.getParentId());
			if (parentOption.isPresent()) {
				existEntity.setParent(parentOption.get());
			}
		}
		if (null != vo.getWorkGroupId()) {
			// 检查工作组是否存在
			Optional<WorkGroupEntity> option = workGroupRepository.findById(vo.getWorkGroupId());
			if (option.isPresent()) {
				existEntity.setWorkGroup(option.get());
			} else {
				throw new BusinessException(ExceptionCodeEnum.WORK_GROUP_NOT_EXIST);
			}
		}

		BeanUtils.copyProperties(vo, existEntity, "avatar");
		if (!ObjectUtils.isEmpty(vo.getAvatar()) && vo.getAvatar().startsWith(BASE64_PRX)) {
			existEntity.setAvatar(transBaseToFile(existEntity.getLogin(), vo.getAvatar()));
		}
		// 一个域下面只能存在一个leader
		if (vo.getOrgRole() == 2) {
			c = new ExpandCriteria<>();
			c.add(Restrictions.ne("id", id, true));
			c.add(Restrictions.eq(FIELD_ORGROLE, vo.getOrgRole(), true));
			c.add(Restrictions.eq(FIELD_WORKGROUP, vo.getWorkGroupId(), true));
			list = orgChartRepository.findAll(c);
			if (CollUtil.isNotEmpty(list)) {
				throw new BusinessException(ExceptionCodeEnum.ORG_CHART_HAS_EXIST);
			}
		}
		orgChartRepository.save(existEntity);
	}

	@Override
	public List<OrgChartEntity> getOrgChart() {
		ExpandCriteria<OrgChartEntity> c = new ExpandCriteria<>();
		c.add(Restrictions.isNull("parent"));
		return orgChartRepository.findAll(c);
	}

	@Override
	public List<OrgChartEntity> getOrgChartByWorkGroupId(Long id) {
		ExpandCriteria<OrgChartEntity> c = new ExpandCriteria<>();
		c.add(Restrictions.eq(FIELD_WORKGROUP, id, true));
		// ITMT Leader:2，ITMT SubLeader:3，ITMT成员:4
		c.add(Restrictions.or(Restrictions.eq(FIELD_ORGROLE, 2, true), Restrictions.eq(FIELD_ORGROLE, 3, true),
				Restrictions.eq(FIELD_ORGROLE, 4, true)));
		Sort sort = Sort.by(Sort.Direction.ASC, "nickName");
		return orgChartRepository.findAll(c, sort);
	}

	/**
	 * 保存base64图片信息到本地文件
	 *
	 * @param login
	 * @param base64
	 * @return
	 */
	private String transBaseToFile(String login, String base64) {
		base64 = base64.replaceFirst(BASE64_PRX, "");
		String fileName = login + ".jpeg";
		Path dstFilePath = genUploadFilePath(fileName);
		try {
			Base64Utils.generateImage(base64, dstFilePath.toString());
		} catch (IOException e) {
			e.printStackTrace();
		}
		return dstFilePath.toString();
	}

	private Path genUploadFilePath(String fileName) {
		Path uploadPath = Path.of(fileRootPath, "avatar");
		File uploadFolder = uploadPath.toFile();
		if (!uploadFolder.exists()) {
			uploadFolder.mkdirs();
		}
		return Paths.get(uploadPath.toString(), fileName);
	}

	@Override
	public Object getOrgInfo(Integer orgRole) {
		ExpandCriteria<OrgChartEntity> c = new ExpandCriteria<>();
		// ITMT Leader:2，ITMT SubLeader:3，ITMT成员:4
		c.add(Restrictions.eq(FIELD_ORGROLE, orgRole, true));
		List<OrgChartEntity> list = orgChartRepository.findAll(c);
		return list.stream().map(o -> o.getLogin()).toList();
	}

	/**
	 * ITMT ChairMan:1，ITMT Leader:2，ITMT SubLeader:3，ITMT成员:4,TSP:5,PRG:6
	 * 
	 * @param orgRole
	 * @return
	 */
	@Override
	public Object getOrgInfoByOrgRole(Integer orgRole) {
		ExpandCriteria<OrgChartEntity> c = new ExpandCriteria<>();
		c.add(Restrictions.eq(FIELD_ORGROLE, orgRole, true));
		return orgChartRepository.findAll(c);
	}

	/**
	 * 判断用户是否属于角色成员
	 *
	 * @param orgRole
	 *            组织角色:ITMT ChairMan:1，ITMT Leader:2，ITMT
	 *            SubLeader:3，ITMT成员:4，TSP:5
	 * @param login
	 * @return
	 */
	@Override
	public List<OrgChartEntity> getUserWorkGroup(Integer orgRole, String login) {
		ExpandCriteria<OrgChartEntity> c = new ExpandCriteria<>();
		// 组织角色:ITMT ChairMan:1，ITMT Leader:2，ITMT SubLeader:3，ITMT成员:4，TSP:5
		c.add(Restrictions.eq(FIELD_ORGROLE, orgRole, true));
		c.add(Restrictions.eq(FIELD_LOGIN, login, true));
		return orgChartRepository.findAll(c);
	}

	/**
	 * 判断用户是否属于角色成员
	 *
	 * @param orgRole
	 *            组织角色:ITMT ChairMan:1，ITMT Leader:2，ITMT
	 *            SubLeader:3，ITMT成员:4，TSP:5
	 * @param workGroupId
	 * @return
	 */
	@Override
	public List<OrgChartEntity> getUserByWorkGroup(Integer orgRole, Long workGroupId) {
		ExpandCriteria<OrgChartEntity> c = new ExpandCriteria<>();
		// 组织角色:ITMT ChairMan:1，ITMT Leader:2，ITMT SubLeader:3，ITMT成员:4，TSP:5
		c.add(Restrictions.eq(FIELD_ORGROLE, orgRole, true));
		c.add(Restrictions.eq(FIELD_WORKGROUP, workGroupId, true));
		return orgChartRepository.findAll(c);
	}

	@Override
	public Object getUserWorkGroup() {
		ExpandCriteria<OrgChartEntity> c = new ExpandCriteria<>();
		String userLogin = ControllerCommonUtils.getHeader(PangooWebConstant.HEADER_NAME_USER_ID);
		// 组织角色:ITMT ChairMan:1，ITMT Leader:2，ITMT SubLeader:3，ITMT成员:4，TSP:5
		c.add(Restrictions.in(FIELD_ORGROLE, Arrays.asList(2, 3), true));
		c.add(Restrictions.eq(FIELD_LOGIN, userLogin, true));
		List<OrgChartEntity> list = orgChartRepository.findAll(c);
		return list.stream().map(item -> item.getWorkGroup()).collect(Collectors.toSet());
	}
}
